home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 2 / LSD and 17bit Compendium Deluxe - Volume II.iso / a / prog / asmsrc / thesource-7.lha / Source / DefFunc.lha / DefFunc / dfcsymtable.c < prev    next >
C/C++ Source or Header  |  1993-12-14  |  12KB  |  548 lines

  1. /*********************************************************
  2.  *
  3.  *    Copyright (c) 1993  Ke Jin
  4.  *
  5.  *    Permission to use, copy, modify, and distribute
  6.  *    this software and its documentation without fee
  7.  *    is granted, provided that the author's name and
  8.  *    this copyright notice are retained.
  9.  *
  10.  * -----------------------------------------------------
  11.  *
  12.  *    dfcsymtable.c -- symbol table of defunc
  13.  *
  14.  *    public  function : getsym(); 
  15.  *                       getfnctname();
  16.  *                       getarguname();
  17.  *
  18.  *                       nameargu();
  19.  *                       initargu();
  20.  *                       namefnct();
  21.  *                       namecnst();
  22.  *                       clrfnct();
  23.  *                       clrfnctall();
  24.  *                       clrcnst();
  25.  *                       clrcnstall();
  26.  *
  27.  *                       matha2z();  
  28.  *
  29.  *    private variable : sym_table;
  30.  *                       tablen;
  31.  *
  32.  *    private function : top();
  33.  *                       isname();
  34.  *                       clrname();
  35.  *                       clrall();
  36.  *
  37.  *********************************************************/
  38.  
  39. #include <stdio.h>
  40. #include <malloc.h>
  41. #include <string.h>
  42. #include <math.h>
  43. #include <ctype.h>
  44. #include "dfcsymtable.h"
  45.  
  46. #ifdef __cplusplus
  47.   extern "C" {   /* for c++ */
  48. #endif
  49.  
  50. static Symbol_record* sym_table = 0; 
  51. /* The defunc system global name-object association table */
  52.  
  53. #if NeedFunctionPrototypes
  54.   Symbol_record* getsym(char *name) 
  55. #else
  56.   Symbol_record* getsym(name)   
  57.   char *name;
  58. #endif
  59. /* search for record with the given name from sym_table */
  60. {
  61.     Symbol_record* ptr;
  62.  
  63.     if(name==0) return 0;
  64.  
  65.     for(ptr=sym_table; ptr!=0; ptr=(Symbol_record*)ptr->next)
  66.     {
  67.        if(strcmp(ptr->name, name)==0) break;
  68.     }
  69.  
  70.     return ptr;  
  71.        /* if symbol with name not in sym_table, return will be NULL */
  72. };
  73.  
  74. #if NeedFunctionPrototypes
  75.   char* getfnctname(double (*fnct)())
  76. #else
  77.   char* getfnctname(fnct)
  78.   double (*fnct)();
  79. #endif
  80. {
  81.     Symbol_record* ptr;
  82.  
  83.     for(ptr=sym_table;ptr!=0;ptr=ptr->next)
  84.     {
  85.         if(ptr->type==fnct_symbol)
  86.         {
  87.             if(fnct==ptr->content.fnctptr) return ptr->name;
  88.         }
  89.     }
  90.             
  91.     return 0;
  92. };
  93.  
  94. #if NeedFunctionPrototypes
  95.   char* getarguname(int argidx)
  96. #else
  97.   char* getarguname(argidx)
  98.   int argidx;
  99. #endif
  100. /* return the name of the argument with specific index */ 
  101. {
  102.     Symbol_record* ptr;
  103.  
  104.     for(ptr=sym_table; ptr!=0; ptr=ptr->next)
  105.     {
  106.         if(ptr->type==arg_symbol)
  107.         {
  108.             if(argidx==ptr->content.argidx) return ptr->name;
  109.         }    
  110.     }
  111.  
  112.     return 0;
  113. };
  114.  
  115. #if NeedFunctionPrototypes
  116.   static Symbol_record* top(void)
  117. #else
  118.   static Symbol_record* top() 
  119. #endif
  120. /* return the top symbol record in the sym_table heap */
  121. {
  122.     Symbol_record* ptr;
  123.  
  124.     for(ptr=sym_table; ptr->next!=0; ptr=(Symbol_record*)ptr->next) 
  125.     { 
  126.     /* skim over the table, do nothing on it */ 
  127.     };
  128.  
  129.     return ptr;
  130. };
  131.  
  132. #if NeedFunctionPrototypes
  133.   static int isname(char* str)
  134. #else
  135.   static int isname(str)
  136.   char *str;
  137. #endif
  138. /* Is the string str a legal name? (start with alphabetic character
  139.  * followed by alphabetics or numberical characters) */
  140. {
  141.     int i;
  142.  
  143.     if(str==0||strlen(str)==0) return 0;
  144.  
  145.     if(!isalpha(str[0])) return 0; /* fail */
  146.  
  147.     for(i=1;i<strlen(str);i++)
  148.     {
  149.     if(!isalnum(str[i])) return 0;  /* fail */
  150.     }
  151.  
  152.     return 1; /* true */
  153. };
  154.  
  155. #if NeedFunctionPrototypes
  156.   static int clrname(char* name, Symbol_type type)
  157. #else
  158.   static int clrname(name, type)
  159.   char* name;
  160.   Symbol_type type;
  161. #endif
  162. /* delete a specific name with given type from symbol table */
  163. {
  164.     Symbol_record *ptr=sym_table, *newnext;
  165.  
  166.     if(sym_table==0) return 0;    /* empty table, no delete action */
  167.  
  168.     if(strcmp(sym_table->name, name)==0&&ptr->type==type)
  169.     /* name and type matched with the 1st record */
  170.     {
  171.     ptr = sym_table;
  172.     sym_table = sym_table->next;     /* cut out the 1st record */
  173.     free(ptr->name);           
  174.     free(ptr);
  175.     return 1;
  176.     }
  177.  
  178.     for(ptr=sym_table; ptr->next!=0; ptr=(Symbol_record*)ptr->next)
  179.     /* skim through the table */
  180.     {
  181.     if(strcmp(ptr->next->name, name)==0&&ptr->next->type==type)
  182.     /* name and type matched with the next record */
  183.     {
  184.         newnext=ptr->next->next; /* cut out the next record */
  185.         free(ptr->next->name);
  186.         free(ptr->next);
  187.         ptr->next=newnext;
  188.         return 1;
  189.         }
  190.     }
  191.  
  192.     return 0;  /* no matching */
  193. };
  194.  
  195. #if NeedFunctionPrototypes
  196.   int clrfnct(char* name)
  197.       { return clrname(name, fnct_symbol);};
  198.   int clrcnst(char* name)
  199.       { return clrname(name, const_symbol);};
  200. #else
  201.   int clrfnct(name) char* name;
  202.       { return clrname(name, fnct_symbol);};
  203.   int clrcnst(name) char* name; 
  204.       { return clrname(name, const_symbol);};
  205. #endif
  206.  
  207. #if NeedFunctionPrototypes
  208.   static int clrall(Symbol_type type)
  209. #else
  210.   static int clrall(type)
  211.   Symbol_type type;
  212. #endif
  213. /* delete all symbols with specific type from symbol table */
  214. {
  215.     Symbol_record* ptr, *newnext;
  216.     int i=0; 
  217.  
  218.     if(sym_table==0) return 0;   /* empty, no delete action */
  219.  
  220.     for(ptr=sym_table;sym_table!=0;ptr=sym_table)
  221.                 /* always point to 1st record */
  222.     {
  223.         if(sym_table->type==type)    /* type matched with the 1st record */
  224.         {
  225.         sym_table=sym_table->next; /* cut out the 1st record */
  226.         free(ptr->name);
  227.         free(ptr);
  228.         i++;
  229.         }
  230.     else break;   /* if new 1st record not match, jump out */
  231.     }
  232.  
  233.     if(sym_table == 0) return i;  /* still have record ? */
  234.  
  235.     for(ptr=sym_table; ptr->next!=0; ptr=(Symbol_record*)ptr->next)
  236.     /* skim through the table */
  237.     {
  238.     if(ptr->next->type==type) /* type matched with next record */
  239.     {
  240.         newnext = ptr->next->next;  /* cut out the next record */
  241.         free(ptr->next->name);
  242.         free(ptr->next);
  243.         ptr->next = newnext;
  244.         i++;
  245.         }
  246.     }
  247.  
  248.     return i;
  249. };
  250.  
  251. #if NeedFunctionPrototypes
  252.   int clrfnctall(void)
  253.       { return clrall(fnct_symbol);};
  254.   int clrcnstall(void)
  255.       { return clrall(const_symbol);};
  256. #else
  257.   int clrfnctall()
  258.       { return clrall(fnct_symbol);};
  259.   int clrcnstall()
  260.       { return clrall(const_symbol);};
  261. #endif
  262.  
  263. #if NeedFunctionPrototypes
  264.   int namefnct(char* str, double (*fnctptr)())
  265. #else
  266.   int namefnct(str, fnctptr)   
  267.   char *str;
  268.   double (*fnctptr)();
  269. #endif
  270. /* add a function symbol to the end of sym_table */
  271. {
  272.     Symbol_record* ptr=0; 
  273.  
  274.     if(!isname(str)||fnctptr==0) return 0;
  275.  
  276.     if(sym_table==0) /* table is empty */
  277.     {
  278.     if(nameargu("x", "y")<=0) return -1;
  279.     }
  280.  
  281.     ptr = getsym(str);
  282.  
  283.     if(ptr==0) /* symbol not exist in sym_table */
  284.     {
  285.         ptr = top()->next  
  286.             = (Symbol_record*)malloc(sizeof(Symbol_record));
  287.         if(ptr==0)
  288.     {
  289.         perror("malloc for new function token item");
  290.         exit(1);
  291.         }
  292.     }
  293.     else if(ptr->type==arg_symbol)
  294.     {
  295.         return -1;  /* forbiding override argument symbols */
  296.     }
  297.  
  298.     ptr->name = (char*)malloc((strlen(str)+1)*sizeof(char));
  299.     if(ptr->name==0)
  300.     {
  301.     perror("malloc for new function token name");
  302.     exit(1);
  303.     }
  304.     
  305.     strncpy(ptr->name, str, strlen(str)+1);
  306.     ptr->type = fnct_symbol;
  307.     ptr->content.fnctptr = fnctptr;
  308.  
  309.     return 1;
  310. };
  311.  
  312. #if NeedFunctionPrototypes
  313.   int namecnst(char* str, double number)
  314. #else
  315.   int namecnst(str, number)  
  316.   char *str;
  317.   double number;
  318. #endif
  319. /* add a constnat symbol to the end of sym_table */
  320. {
  321.     Symbol_record* ptr=0;
  322.  
  323.     if(!isname(str)) return 0;
  324.  
  325.     if(sym_table==0) /* table is empty */
  326.     {
  327.     if(nameargu("x", "y")<=0) return -1;
  328.     } 
  329.  
  330.     ptr = getsym(str);
  331.  
  332.     if(ptr==0) /* symbol not exist in sym_table */
  333.     {
  334.         ptr = top()->next 
  335.             = (Symbol_record*)malloc(sizeof(Symbol_record));
  336.         if(ptr==0)
  337.     {
  338.         perror("malloc for constant token item");
  339.         exit(1);
  340.         }
  341.     }
  342.     else if(ptr->type==arg_symbol)
  343.     {
  344.         return -1;    /* forbiding override argument symbols */
  345.     }
  346.  
  347.     ptr->name = (char*)malloc((strlen(str)+1)*sizeof(char));
  348.     if(ptr->name==0) 
  349.     {
  350.     perror("malloc for constant token name");
  351.     exit(1);
  352.     }
  353.  
  354.     strncpy(ptr->name, str, strlen(str)+1);
  355.     ptr->type = const_symbol;
  356.     ptr->content.value = number;
  357.  
  358.     return 1;
  359. };
  360.  
  361. #if NeedFunctionPrototypes
  362.   int nameargu(char* arg1, char* arg2)
  363. #else
  364.   int nameargu(arg1, arg2)
  365.   char *arg1, *arg2;
  366. #endif
  367. /* on error return -1, on success return 1, if no change return 0 */
  368. {
  369.     if(!isname(arg1)) return 0;
  370.  
  371.     if(!isname(arg2)) arg2 = "_";
  372.  
  373.     if(strcmp(arg1, arg2)==0) return -1;  /* stupid */
  374.  
  375.     clrname(arg1, fnct_symbol);
  376.     clrname(arg1, const_symbol);
  377.     clrname(arg2, fnct_symbol);
  378.     clrname(arg2, const_symbol);
  379.  
  380.     if(sym_table==0)
  381.     {
  382.     sym_table = (Symbol_record*)malloc(sizeof(Symbol_record));
  383.     if(sym_table==0)
  384.     {
  385.         perror("malloc for the 1st argument token item");
  386.         exit(1);
  387.         }
  388.     }
  389.  
  390.     sym_table->name = (char*)malloc((strlen(arg1)+1)*sizeof(char));
  391.     if(sym_table->name==0)
  392.     {
  393.     perror("malloc for the 1st argument token name");
  394.     exit(1);
  395.     }
  396.  
  397.     strncpy(sym_table->name, arg1, strlen(arg1)+1);
  398.     sym_table->type = arg_symbol;
  399.     sym_table->content.argidx = 1;
  400.  
  401.     if(sym_table->next==0)
  402.     {
  403.     sym_table->next = (Symbol_record*)malloc(sizeof(Symbol_record));
  404.     if(sym_table->next==0)
  405.     {
  406.         perror("malloc for the 2nd token token item");
  407.         exit(1);
  408.         }
  409.     }
  410.  
  411.     sym_table->next->name = (char*)malloc((strlen(arg2)+1)*sizeof(char));
  412.     if(sym_table->next->name==0)
  413.     {
  414.     perror("alloc memory for 2nd arguement name");
  415.         exit(1);
  416.     }
  417.  
  418.     strncpy(sym_table->next->name, arg2, strlen(arg2)+1);
  419.  
  420.     sym_table->next->type = arg_symbol;
  421.     sym_table->next->content.argidx = 2;
  422.  
  423.     return 1;
  424. };
  425.  
  426. #if NeedFunctionPrototypes
  427.   int initargu(void)
  428. #else
  429.   int initargu()
  430. #endif
  431. /* if no argument names then use default */
  432. {
  433.     if(sym_table==0) return nameargu("x", "y");
  434.     return 0;
  435. };
  436.  
  437. static struct {
  438.     char* name;
  439.     double (*fnctptr)();
  440. } initfnct[] = {
  441.     "sin"  , sin  ,
  442.     "cos"  , cos  ,
  443.     "tan"  , tan  , 
  444.     "tg"   , tan  ,
  445.     "asin" , asin ,
  446.     "acos" , acos ,
  447.     "atan" , atan ,
  448.     "atan2", atan2,
  449.     "exp"  , exp  ,
  450.     "sinh" , sinh ,
  451.     "sh"   , sinh ,
  452.     "cosh" , cosh ,
  453.     "ch"   , cosh ,
  454.     "tanh" , tanh ,
  455.     "th"   , tanh ,
  456.     "asinh", asinh,
  457.     "ash"  , asinh,
  458.     "acosh", acosh,
  459.     "ach"  , acosh,
  460.     "atanh", atanh,
  461.     "ath"  , atanh,
  462.     "pow"  , pow  ,
  463.     "log"  , log  ,
  464.     "ln"   , log  ,
  465.     "log10", log10,
  466.     "log2" , log2 ,
  467.     "sqrt" , sqrt ,
  468.     "abs"  , fabs ,
  469.     0      , 0      };
  470.  
  471. #if NeedFunctionPrototypes
  472.   int matha2z(void)
  473. #else
  474.   int matha2z()
  475. #endif
  476. /* set up a symbol table include math "a to z" functions */
  477. {
  478.     int i=0, j=0;
  479.  
  480.     initargu();
  481.  
  482.     for(i=0;initfnct[i].name!=0;i++)
  483.     {
  484.         j = j + namefnct(initfnct[i].name, initfnct[i].fnctptr); 
  485.     }
  486.  
  487.     j = j + namecnst("pi", 2*asin(1.0));
  488.  
  489.     return j;
  490. };
  491.  
  492. /* codes for debug  -------------------------------------------  */
  493.  
  494. #if NeedFunctionPrototypes
  495.   int printrec(Symbol_record* ptr, double x)
  496. #else
  497.   int printrec(ptr, x)
  498.   Symbol_record* ptr;
  499.   double x;
  500. #endif
  501. {
  502.     printf("type = %d\n", ptr->type);
  503.     if(ptr->name!=0) printf("name = %s\n", ptr->name);
  504.    
  505.     switch(ptr->type)
  506.     {
  507.     case const_symbol:
  508.          printf("value= %f\n", ptr->content.value);
  509.          break;
  510.  
  511.         case arg_symbol:
  512.          printf("arg[%d] = %s\n", ptr->content.argidx,
  513.                       getfnctname(ptr->content.fnctptr));
  514.          break;
  515.  
  516.         case fnct_symbol:
  517.          printf("%s(%f) = %f\n", ptr->name, x, (ptr->content.fnctptr)(x));
  518.              break;
  519.  
  520.         default: break;
  521.     }
  522.  
  523.     return 0;
  524. };
  525.  
  526. #if NeedFunctionPrototypes
  527.   int printab(double x)
  528. #else
  529.   int printab(x)
  530.   double x;
  531. #endif
  532. {
  533.     Symbol_record* ptr;
  534.     int len = 0;
  535.  
  536.     for(ptr=sym_table; ptr!=0; ptr=ptr->next)
  537.     {
  538.        len ++;
  539.        printrec(ptr, x);
  540.     }
  541.  
  542.     return len;
  543. };
  544.  
  545. #ifdef __cplusplus
  546.   }    /* end for c++ */
  547. #endif
  548.